package com.cloudfun.campusshare.annotation;

import cn.hutool.core.util.ReflectUtil;
import com.cloudfun.campusshare.common.model.vo.ImageVo;
import com.cloudfun.campusshare.entity.AttachmentEntity;
import com.cloudfun.campusshare.service.AttachmentService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.*;
import java.util.List;

/**
 * 根据图片id查询补充图片地址
 * 注意该注解请求在get时不起作用
 */
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {
        ImageSetUrl.SetUrl.class,
        ImageSetUrl.SetUrls.class,
})
@Documented
public @interface ImageSetUrl {

    String message() default "com.cloudfun.campusshare.annotation.ImageSetUrl.message";

    Class<?>[] groups() default {};

    String methodName();

    Class<? extends Payload>[] payload() default {};

    class SetUrl implements ConstraintValidator<ImageSetUrl, ImageVo> {
        private ImageSetUrl imageSetUrl;
        @Autowired
        private AttachmentService attachmentService;

        @Override
        public void initialize(ImageSetUrl constraintAnnotation) {
            imageSetUrl = constraintAnnotation;
        }

        @Override
        public boolean isValid(ImageVo vo, ConstraintValidatorContext constraintValidatorContext) {
            if (vo == null) {
                return true;
            }
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            Object target = request.getAttribute("target");
            AttachmentEntity attach = attachmentService.getAttach(vo.getId());
            if (attach == null) {
                return false;
            }
            vo.setName(attach.getName());
            vo.setUrl(attach.getUrl());
            ReflectUtil.invoke(target, imageSetUrl.methodName(), vo);
            return true;
        }
    }

    class SetUrls implements ConstraintValidator<ImageSetUrl, List<ImageVo>> {
        private ImageSetUrl imageSetUrl;
        @Autowired
        private AttachmentService attachmentService;

        @Override
        public void initialize(ImageSetUrl constraintAnnotation) {
            imageSetUrl = constraintAnnotation;
        }

        @Override
        public boolean isValid(List<ImageVo> vo, ConstraintValidatorContext constraintValidatorContext) {
            if (vo == null) {
                return true;
            }
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            Object target = request.getAttribute("target");
            vo.forEach(imageVo -> {
                AttachmentEntity attach = attachmentService.getAttach(imageVo.getId());
                if (attach == null) {
                    return;
                }
                imageVo.setName(attach.getName());
                imageVo.setUrl(attach.getUrl());
            });
            ReflectUtil.invoke(target, imageSetUrl.methodName(),vo);
            return true;
        }
    }
}
